/**
 * 判断数据类型
 */
export function getDataType(obj: unknown): string {
  const toString = Object.prototype.toString
  const map: {
    [key: string]: string
  } = {
    '[object Boolean]': 'boolean',
    '[object Number]': 'number',
    '[object String]': 'string',
    '[object Function]': 'function',
    '[object Array]': 'array',
    '[object Date]': 'date',
    '[object RegExp]': 'regExp',
    '[object Undefined]': 'undefined',
    '[object Null]': 'null',
    '[object Object]': 'object',
  }
  if (obj instanceof Element) {
    return 'element'
  }
  return map[toString.call(obj)]
}

/**
 * 对象深拷贝
 */
export function deepClone<T>(target: T): T {
  // 判断是否是基本数据类型
  if (typeof target !== 'object' || target === null) {
    return target
  }

  // 处理特殊对象类型
  if (target instanceof Date) {
    return new Date(target.getTime()) as T
  }

  if (Array.isArray(target)) {
    return target.map((item) => deepClone(item)) as unknown as T
  }

  if (target instanceof Map) {
    const map = new Map()
    target.forEach((value, key) => {
      map.set(key, deepClone(value))
    })
    return map as unknown as T
  }

  if (target instanceof Set) {
    const set = new Set()
    target.forEach((value) => {
      set.add(deepClone(value))
    })
    return set as unknown as T
  }

  // 普通对象
  const clonedObj: Record<string, unknown> = {}
  for (const key in target) {
    if (Object.prototype.hasOwnProperty.call(target, key)) {
      clonedObj[key] = deepClone((target as Record<string, unknown>)[key])
    }
  }
  return clonedObj as T
}

/**
 * 根据字典的value查找对应的index
 */
export const findIndexInArray = (
  dic: {
    label: string
    value: string | number | boolean
  }[],
  value: string | number | boolean,
) => {
  for (let i = 0; i < dic.length; i++) {
    if (dic[i].value === value) {
      return i
    }
  }
  return -1
}

// 表单序列化
export const serialize = (data: { [x: string]: unknown }) => {
  const list: string[] = []
  Object.keys(data).forEach((ele) => {
    list.push(`${ele}=${data[ele]}`)
  })
  return list.join('&')
}

type TreeNode<T> = T & {
  children?: TreeNode<T>[]
}

/**
 * 获取树节点的父节点
 * @param tree 树形数组
 * @param targetNode 要查找的目标节点
 * @param options 配置项
 * @returns 父节点或 undefined（如果目标节点是根节点或不存在）
 */
export function findParentNode<T>(
  tree: TreeNode<T>[],
  targetNode: TreeNode<T>,
  options?: { idKey?: keyof T; childrenKey?: string },
): TreeNode<T> | undefined | null {
  const { idKey, childrenKey = 'children' } = options || {}

  // 辅助函数：递归查找
  function dfs(nodes: TreeNode<T>[], parent: TreeNode<T> | null): TreeNode<T> | undefined | null {
    for (const node of nodes) {
      // 检查当前节点是否为目标节点
      if ((idKey && node[idKey] === targetNode[idKey]) || (!idKey && node === targetNode)) {
        return parent
      }

      // 如果有子节点，递归查找
      const children = node[childrenKey as keyof TreeNode<T>] as TreeNode<T>[]
      if (children && children.length > 0) {
        const found = dfs(children, node)
        if (found) return found
      }
    }
    return undefined
  }

  // 从根节点开始查找
  return dfs(tree, null)
}
/**
 * 生成基于时间戳的唯一ID
 * @param prefix 可选前缀
 * @returns 唯一ID字符串
 */
export function generateTimestampId(prefix: string = ''): string {
  const timestamp = Date.now().toString(36)
  const randomPart = Math.random().toString(36).substring(2, 8)
  return `${prefix ? prefix + '_' : ''}${timestamp}_${randomPart}`
}
